﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CookComputing.XmlRpc;
using System.Windows;
using System.ComponentModel.Composition;
using System.IO;
using wiki2doc.Properties;
using System.Text.RegularExpressions;

namespace wiki2doc
{
    [Export(typeof(IWikiDownload))]
    [ExportMetadata("Name", "DokuWiki")]
    public class DokuWikiDownload : IWikiDownload
    {
        IDokuWiki proxy;
        List<string> topics;

        [Import("StatusMessage")]
        Action<string> StatusMessage;

        private string prv_workfolder;
        private  int topic_nr;

        public DokuWikiDownload ()
        {
            proxy = XmlRpcProxyGen.Create<IDokuWiki>();
            prv_workfolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\Temp\wiki2doc";
            topics = new List<string>();
            topic_nr = 0;
        }

        public List<string> Download(IConfiguration configuration)
        {
            proxy.Url = configuration.URL + "/lib/exe/xmlrpc.php?u=" + configuration.Username + "&p=" + configuration.Password;

            // prepare source workfolder
            PrepareSourceWorkfolder();

            // reset topics
            topics.Clear();

            // get start page
            GetStartPage(configuration.Namespace);

            // travers the table of content and download all wiki pages
            GetFilesFromStartPage(configuration.Namespace);

            StatusMessage("Download complete");
            return topics;
        }

        private void GetFilesFromStartPage(string nmspace)
        {
            var links = proxy.listLinks(nmspace + ":start");
            foreach( var link in links )
            {
                GetTopic(link.page, nmspace);
            }
        }

        private void GetTopic(string topic, string nmspace)
        {
            
            if ( topics.Contains(topic) )
            {
                StatusMessage("Topic already downloaded: " + topic);
                return;
            }

            StatusMessage("Topic " + topic);

            var wf = prv_workfolder + @"\source";
            topic_nr += 1;

            // determine html filename
            var html_file = topic.Replace("?", "");
            html_file = html_file.Replace("/", "-");
            html_file = html_file.Replace("  ", " ");

            string html_content;
            string topic_content;
            // get the topic content and its html content
            if (topic.Contains( ":") )
            {
                topic_content = proxy.getPage(topic);
                html_content = proxy.getPageHTML(topic);
                html_file = html_file.Replace(":", "-");
            }
            else
            {
                topic_content = proxy.getPage(nmspace + ":" + topic);
                html_content = proxy.getPageHTML(nmspace + ":" + topic);
            }

            // Get attachments
            GetAttachments(topic_content);

            // add topic to list of topics
            topics.Add(topic);

            // create the xhtml file content
            string html = Resources.xhtml_template.ToString();
            html_content = html.Replace("{{html_content}}", html_content);

            // write topic and html to disc
            File.WriteAllText(wf + @"\text\" + html_file + ".txt", topic_content, Encoding.UTF8);
            File.WriteAllText(wf + @"\xhtml\" + html_file + ".html", html_content, Encoding.UTF8);

        }

        private void GetAttachments(string topic_content)
        {
        
            var myregEx = new Regex("{{([^}]*?)}}");
            var wf = prv_workfolder + @"\source\images\";
            var myMatches = myregEx.Matches(topic_content);

            // Search for all the words in a string
        
            foreach( Match successfulMatch in myMatches)
            {
                var e = successfulMatch.Value;
                string l;
                e = e.TrimStart('{');
                e = e.TrimEnd('}');

                try 
                {	        
                    l = e.Split('|')[0];
                }
                catch (Exception)
                {
                    l = e;
                }
                
                if ( l.Contains("?"))
                {
                    // strip 'arguments'
                    l = l.Substring(0, (l.IndexOf("?")));
                }

                var att = proxy.getAttachment(l);
                var p = l.LastIndexOf(":");
                var fn = wf + l.Substring(p+1);
                
                File.WriteAllBytes(fn, att);
                

            }
        }

        private void GetStartPage(string nmspace)
        {
            // get start page and store it as text for later processing
            var content = proxy.getPage(nmspace + ":start");

            content = content.Replace("\n", "\r\n");
            File.WriteAllText(prv_workfolder + @"\source\start.txt", content, Encoding.UTF8);

        }

        private void PrepareSourceWorkfolder()
        {

            // clear work folder
            try
            {
                Directory.Delete(prv_workfolder + @"\source", true);
            }
            catch (Exception)
            {
                // nothing to delete
            }

            // create source folder structure
            Directory.CreateDirectory(prv_workfolder);
            Directory.CreateDirectory(prv_workfolder + @"\source");
            Directory.CreateDirectory(prv_workfolder + @"\source\xhtml");
            Directory.CreateDirectory(prv_workfolder + @"\source\text");
            Directory.CreateDirectory(prv_workfolder + @"\source\images");
        }
    }
}
